#include "LightEffects.h"

Effect::LightEffects::LightEffects( )
	:m_pDevice(NULL)
	,m_pFx(NULL)
	,m_pInputLayout(NULL)
	,m_pFxTech(NULL)
	,m_pFxDiffuseMapVar(NULL)
	,m_pFxSpecMapVar(NULL)
	,m_pFxWVPVar(NULL)
	,m_pFxWorldVar(NULL)
	,m_pFxTexMtxVar(NULL)
	,m_pFxEyePosVar(NULL)
	,m_pFxLightVar(NULL)
{
	//if(!m_pDevice)
	//	MessageBoxA(0, "Error", 0, 0);
}

Effect::LightEffects::~LightEffects( void )
{
	
}

void Effect::LightEffects::BuildFX()
{
	DWORD shaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	shaderFlags |= D3D10_SHADER_DEBUG;
	shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION;
#endif

	ID3D10Blob* compilationErrors = 0;
	HRESULT hr = 0;
	hr = D3DX10CreateEffectFromFile(L"ParallelLight.fx", 0, 0, 
		"fx_4_0", shaderFlags, 0, m_pDevice, 0, 0, &m_pFx, &compilationErrors, 0);
	if(FAILED(hr))
	{
		if( compilationErrors )
		{
			MessageBoxA(0, (char*)compilationErrors->GetBufferPointer(), 0, 0);
			ReleaseCOM(compilationErrors);
		}
		DXTrace(__FILE__, (DWORD)__LINE__, hr, L"D3DX10CreateEffectFromFile", true);
	} 

	m_pFxTech = m_pFx->GetTechniqueByName("ParallelLighting");

	m_pFxWVPVar        = m_pFx->GetVariableByName("gWVP")->AsMatrix();
	m_pFxWorldVar      = m_pFx->GetVariableByName("gWorld")->AsMatrix();
	m_pFxEyePosVar     = m_pFx->GetVariableByName("gEyePosW");
	m_pFxLightVar      = m_pFx->GetVariableByName("gLight");
	m_pFxDiffuseMapVar = m_pFx->GetVariableByName("gDiffuseMap")->AsShaderResource();
	m_pFxSpecMapVar    = m_pFx->GetVariableByName("gSpecMap")->AsShaderResource();
	m_pFxTexMtxVar     = m_pFx->GetVariableByName("gTexMtx")->AsMatrix();
}

void Effect::LightEffects::BuildVertexLayouts()
{
	// Create the vertex input layout.
	D3D10_INPUT_ELEMENT_DESC vertexDesc[] =
	{
		{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{"NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
	};

	// Create the input layout
	D3D10_PASS_DESC PassDesc;
	m_pFxTech->GetPassByIndex(0)->GetDesc(&PassDesc);
	HR(m_pDevice->CreateInputLayout(vertexDesc, 3, PassDesc.pIAInputSignature,
		PassDesc.IAInputSignatureSize, &m_pInputLayout));
}

void Effect::LightEffects::SetWorldMatrix( const D3DXMATRIX& matWorld )
{
	m_pFxWorldVar->SetMatrix((float*)&matWorld);
}

void Effect::LightEffects::SetTextureMatrix( const D3DXMATRIX& matTex )
{
	m_pFxTexMtxVar->SetMatrix((float*)&matTex);
}

void Effect::LightEffects::SetWVPMatrix( const D3DXMATRIX& matWVP )
{
	m_pFxWVPVar->SetMatrix((float*)&matWVP);
}

void Effect::LightEffects::SetEyePos( const D3DXVECTOR3& pos )
{
	m_pFxEyePosVar->SetRawValue((void*)&pos,0,sizeof(D3DXVECTOR3));
}

void Effect::LightEffects::SetLight( const Light& light )
{
	m_pFxLightVar->SetRawValue((void*)&light,0,sizeof(Light));
}

void Effect::LightEffects::SetDiffuseMap( ID3D10ShaderResourceView* resView )
{
	m_pFxDiffuseMapVar->SetResource(resView);
}

void Effect::LightEffects::SetSpecMap( ID3D10ShaderResourceView* resView )
{
	m_pFxSpecMapVar->SetResource(resView);
}

ID3D10InputLayout* Effect::LightEffects::GetInputLayout()
{
	return m_pInputLayout;
}

ID3D10EffectTechnique* Effect::LightEffects::GetEffectTech()
{
	return m_pFxTech;
}

void Effect::LightEffects::Init( ID3D10Device* device )
{
	m_pDevice = device;
}
